package net.xdclass.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.interfaces.Func;
import lombok.extern.slf4j.Slf4j;
import net.xdclass.config.InterceptorConfig;
import net.xdclass.constant.CacheKey;
import net.xdclass.enums.BizCodeEnum;
import net.xdclass.exception.BizException;
import net.xdclass.interceptor.LoginInterceptor;
import net.xdclass.model.LoginUser;
import net.xdclass.request.CartItemRequest;
import net.xdclass.service.CartService;
import net.xdclass.service.ProductService;
import net.xdclass.vo.CartItemVO;
import net.xdclass.vo.CartVO;
import net.xdclass.vo.ProductVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author NJUPT wly
 * @Date 2021/9/18 11:11 下午
 * @Version 1.0
 */
@Service
@Slf4j
public class CartServiceImpl implements CartService {

    @Autowired
    private ProductService productService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 添加商品到购物车
     * @param cartItemRequest
     */
    @Override
    public void addToCart(CartItemRequest cartItemRequest) {

        long productId = cartItemRequest.getProductId();
        int buyNum = cartItemRequest.getBuyNum();

        //获取购物车
        BoundHashOperations<String,Object,Object> myCart = getMyCartOps();

        Object cacheObj = myCart.get(productId);
        String result = "";
        if (cacheObj != null){
            result = (String)cacheObj;
        }

        if (StringUtils.isBlank(result)){
            //不存在则新建一个商品
            CartItemVO cartItemVO = new CartItemVO();
            ProductVO productVO = productService.findDetail(productId);
            if (productVO == null){
                throw new BizException(BizCodeEnum.CART_FAIL);
            }
            cartItemVO.setAmount(productVO.getAmount());
            cartItemVO.setBuyNum(buyNum);
            cartItemVO.setProductId(productId);
            cartItemVO.setProductImg(productVO.getCoverImg());
            cartItemVO.setProductTitle(productVO.getTitle());

            myCart.put(productId, JSON.toJSONString(cartItemVO));

        }else {
            //存在商品，修改数量
            CartItemVO cartItemVO = JSON.parseObject(result,CartItemVO.class);
            cartItemVO.setBuyNum(cartItemVO.getBuyNum() + buyNum);

            myCart.put(productId, JSON.toJSONString(cartItemVO));
        }
    }

    /**
     * 清空购物车
     */
    @Override
    public void clear() {
        String key = getCartKey();
        redisTemplate.delete(key);
    }

    /**
     * 查看我的购物车
     * @return
     */
    @Override
    public CartVO getMyCart() {
        //获取全部的购物项
        List<CartItemVO> cartItemVOList = buildCartItem(true);

        CartVO cartVO = new CartVO();
        cartVO.setCartItems(cartItemVOList);
        return cartVO;
    }

    /**
     * 删除购物项
     * @param productId
     */
    @Override
    public void deleteItem(long productId) {
        BoundHashOperations<String,Object,Object> myCart = getMyCartOps();
        myCart.delete(productId);
    }

    @Override
    public void changeItemNum(CartItemRequest cartItemRequest) {
        BoundHashOperations<String,Object,Object> myCart = getMyCartOps();
        Object cacheObj = myCart.get(cartItemRequest.getProductId());
        if (cacheObj==null){
            throw new BizException(BizCodeEnum.CART_FAIL);
        }
        String obj = (String)cacheObj;
        CartItemVO cartItemVO = JSON.parseObject(obj,CartItemVO.class);
        assert cartItemVO != null;
        cartItemVO.setBuyNum(cartItemRequest.getBuyNum());

        myCart.put(cartItemRequest.getProductId(),JSON.toJSONString(cartItemVO));
    }

    /**
     * 确认购物车最新价格
     * @param productIdList
     * @return
     */
    @Override
    public List<CartItemVO> confirmOrderCartItems(List<Long> productIdList) {
        //获取全部购物车购物项
        List<CartItemVO> cartItemVOList = buildCartItem(true);

        //根据需要id进行过滤,并清空购物
        List<CartItemVO> resultList = cartItemVOList.stream().filter(obj->{
            if (productIdList.contains(obj.getProductId())){
                this.deleteItem(obj.getProductId());
                return true;
            }else {
                return false;
            }
        }).collect(Collectors.toList());

        return resultList;
    }

    /**
     * 抽取我的购物车通用方法
     * @return
     */
    private BoundHashOperations<String,Object,Object> getMyCartOps(){
        String cartKey = getCartKey();
        BoundHashOperations<String,Object,Object> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        return boundHashOperations;
    }

    /**
     * 购物车key
     * @return
     */
    private String getCartKey(){
        LoginUser loginUser = LoginInterceptor.threadLocal.get();

        return String.format(CacheKey.CART_KEY,loginUser.getId());
    }

    /**
     * 获取最新的购物车
     * @param latestPrice
     * @return
     */
    private List<CartItemVO> buildCartItem(boolean latestPrice){
        BoundHashOperations<String,Object,Object> myCart = getMyCartOps();
        List<Object> itemList = myCart.values();
        List<CartItemVO> cartItemVOList = new ArrayList<>();

        //拼接id列表查询最新价格
        List<Long> productIdList = new ArrayList<>();

        assert itemList != null;

        for (Object object:itemList){
            CartItemVO cartItemVO = JSON.parseObject((String) object,CartItemVO.class);
            cartItemVOList.add(cartItemVO);
            productIdList.add(cartItemVO.getProductId());
        }

        //查询最新的商品价格
        if (latestPrice){
            setProductLatestPrice(cartItemVOList,productIdList);
        }
        return cartItemVOList;
    }

    /**
     * 设置商品最新价格
     * @param cartItemVOList
     * @param productIdList
     */
    private void setProductLatestPrice(List<CartItemVO> cartItemVOList, List<Long> productIdList) {
        //批量查询
        List<ProductVO> productVOList = productService.findProductsByIdBatch(productIdList);
        if (productVOList == null){
            throw new BizException(BizCodeEnum.CART_IS_EMPTY);
        }
        //分组
        Map<Long,ProductVO> map = productVOList.stream().collect(Collectors.toMap(ProductVO::getId, Function.identity()));

        cartItemVOList.stream().forEach(cartItemVO -> {
            ProductVO productVO = map.get(cartItemVO.getProductId());
            cartItemVO.setProductTitle(productVO.getTitle());
            cartItemVO.setProductImg(productVO.getCoverImg());
            cartItemVO.setAmount(productVO.getAmount());
        });
    }

}
